package com.charles.config;

import com.charles.enums.ActEvent;
import com.charles.enums.ActivityState;
import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.action.Action;
import org.springframework.statemachine.config.EnableStateMachine;
import org.springframework.statemachine.config.EnumStateMachineConfigurerAdapter;
import org.springframework.statemachine.config.builders.StateMachineConfigurationConfigurer;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;

import java.util.EnumSet;

@Configuration
@EnableStateMachine
public class StatemachineConfigurer extends EnumStateMachineConfigurerAdapter<ActivityState, ActEvent> {
    @Override
    public void configure(StateMachineStateConfigurer<ActivityState, ActEvent> states)
            throws Exception {
        states
                .withStates()
                .initial(ActivityState.NOT_START)
                .states(EnumSet.allOf(ActivityState.class));
    }

    @Override
    public void configure(StateMachineTransitionConfigurer<ActivityState, ActEvent> transitions)
            throws Exception {
        transitions
                .withExternal()
                .source(ActivityState.NOT_START).target(ActivityState.DATA_PREPARING)
                .event(ActEvent.ACT_BEGIN).action(notice())
                .and()
                .withExternal()
                .source(ActivityState.DATA_PREPARING).target(ActivityState.DATA_PREPARED)
                .event(ActEvent.FINISH_DATA_CAL).action(notice())
                .and()
                .withExternal()
                .source(ActivityState.DATA_PREPARED).target(ActivityState.DATA_PUSHING)
                .event(ActEvent.FINISH_DATA_PREPARE).action(notice())
                .and()
                .withExternal()
                .source(ActivityState.DATA_PUSHING).target(ActivityState.FINISHED)
                .event(ActEvent.FINISH_DATA_PUSHING).action(notice())
                .and();
    }

    @Override
    public void configure(StateMachineConfigurationConfigurer<ActivityState, ActEvent> config)
            throws Exception {
        config.withConfiguration()
                .machineId("ActivityStateMachine");
    }

    public Action<ActivityState, ActEvent> notice() {
        return context -> System.out.println("【变更前状态】:" + context.getSource().getId() + ";【变更后状态】:" + context.getTarget().getId());
    }
}